home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / fldpak / fpdemo2e.frm (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1993-11-08  |  20.0 KB  |  580 lines

  1. VERSION 2.00
  2. Begin Form EditFrm 
  3.    BorderStyle     =   1  'Fixed Single
  4.    Caption         =   "Multi-Sortable Address Book (FieldPack demo program 2)"
  5.    ClientHeight    =   2895
  6.    ClientLeft      =   1380
  7.    ClientTop       =   2850
  8.    ClientWidth     =   7215
  9.    ClipControls    =   0   'False
  10.    Height          =   3585
  11.    Icon            =   FPDEMO2E.FRX:0000
  12.    Left            =   1320
  13.    LinkTopic       =   "Form1"
  14.    MaxButton       =   0   'False
  15.    ScaleHeight     =   2895
  16.    ScaleWidth      =   7215
  17.    Top             =   2220
  18.    Width           =   7335
  19.    Begin TextBox txtFindString 
  20.       Height          =   315
  21.       Left            =   1320
  22.       TabIndex        =   23
  23.       Top             =   2460
  24.       Width           =   1155
  25.    End
  26.    Begin ListBox lstSortingListBox 
  27.       Height          =   225
  28.       Left            =   0
  29.       Sorted          =   -1  'True
  30.       TabIndex        =   22
  31.       Top             =   0
  32.       Visible         =   0   'False
  33.       Width           =   1545
  34.    End
  35.    Begin CommandButton cmdSort 
  36.       Caption         =   "Sort by..."
  37.       Height          =   315
  38.       Left            =   5880
  39.       TabIndex        =   21
  40.       Top             =   300
  41.       Width           =   1215
  42.    End
  43.    Begin CommandButton cmdNew 
  44.       Caption         =   "New"
  45.       Height          =   315
  46.       Left            =   5880
  47.       TabIndex        =   20
  48.       Top             =   1080
  49.       Width           =   1215
  50.    End
  51.    Begin CommandButton cmdFind 
  52.       Caption         =   "<--  Find (in current sort field)"
  53.       Height          =   315
  54.       Left            =   2610
  55.       TabIndex        =   19
  56.       Top             =   2460
  57.       Width           =   2805
  58.    End
  59.    Begin CommandButton cmdReport 
  60.       Caption         =   "Report"
  61.       Height          =   315
  62.       Left            =   5880
  63.       TabIndex        =   18
  64.       Top             =   2460
  65.       Width           =   1215
  66.    End
  67.    Begin VScrollBar vscrScroller 
  68.       Height          =   1755
  69.       Left            =   5520
  70.       Min             =   1
  71.       TabIndex        =   7
  72.       Top             =   600
  73.       Value           =   1
  74.       Width           =   255
  75.    End
  76.    Begin CommandButton cmdDelete 
  77.       Caption         =   "Delete"
  78.       Height          =   315
  79.       Left            =   5880
  80.       TabIndex        =   8
  81.       Top             =   1500
  82.       Width           =   1215
  83.    End
  84.    Begin TextBox txtPhone 
  85.       Height          =   315
  86.       Left            =   3000
  87.       TabIndex        =   6
  88.       Top             =   2040
  89.       Width           =   2415
  90.    End
  91.    Begin TextBox txtAreaCode 
  92.       Height          =   315
  93.       Left            =   1320
  94.       TabIndex        =   5
  95.       Top             =   2040
  96.       Width           =   855
  97.    End
  98.    Begin TextBox txtZip 
  99.       Height          =   315
  100.       Left            =   4080
  101.       TabIndex        =   4
  102.       Top             =   1680
  103.       Width           =   1335
  104.    End
  105.    Begin TextBox txtState 
  106.       Height          =   315
  107.       Left            =   1320
  108.       TabIndex        =   3
  109.       Top             =   1680
  110.       Width           =   855
  111.    End
  112.    Begin TextBox txtCity 
  113.       Height          =   315
  114.       Left            =   1320
  115.       TabIndex        =   2
  116.       Top             =   1320
  117.       Width           =   4095
  118.    End
  119.    Begin TextBox txtAddress 
  120.       Height          =   315
  121.       Left            =   1320
  122.       TabIndex        =   1
  123.       Top             =   960
  124.       Width           =   4095
  125.    End
  126.    Begin TextBox txtName 
  127.       Height          =   315
  128.       Left            =   1320
  129.       TabIndex        =   0
  130.       Top             =   600
  131.       Width           =   4095
  132.    End
  133.    Begin Label lblCurrentSortField 
  134.       FontBold        =   -1  'True
  135.       FontItalic      =   -1  'True
  136.       FontName        =   "MS Sans Serif"
  137.       FontSize        =   8.25
  138.       FontStrikethru  =   0   'False
  139.       FontUnderline   =   0   'False
  140.       Height          =   225
  141.       Left            =   4440
  142.       TabIndex        =   25
  143.       Top             =   300
  144.       Width           =   1215
  145.    End
  146.    Begin Label Label9 
  147.       Alignment       =   1  'Right Justify
  148.       Caption         =   "...in sort sequence by:"
  149.       Height          =   225
  150.       Left            =   2400
  151.       TabIndex        =   24
  152.       Top             =   300
  153.       Width           =   1995
  154.    End
  155.    Begin Label lblRecordID 
  156.       Caption         =   " 0 of 0"
  157.       Height          =   195
  158.       Left            =   1380
  159.       TabIndex        =   17
  160.       Top             =   300
  161.       Width           =   975
  162.    End
  163.    Begin Label Label8 
  164.       Alignment       =   1  'Right Justify
  165.       Caption         =   "Record:"
  166.       Height          =   195
  167.       Left            =   60
  168.       TabIndex        =   16
  169.       Top             =   300
  170.       Width           =   1215
  171.    End
  172.    Begin Label Label7 
  173.       Alignment       =   1  'Right Justify
  174.       Caption         =   "Phone:"
  175.       Height          =   195
  176.       Left            =   2220
  177.       TabIndex        =   15
  178.       Top             =   2100
  179.       Width           =   735
  180.    End
  181.    Begin Label Label6 
  182.       Alignment       =   1  'Right Justify
  183.       Caption         =   "Area Code:"
  184.       Height          =   195
  185.       Left            =   60
  186.       TabIndex        =   14
  187.       Top             =   2100
  188.       Width           =   1215
  189.    End
  190.    Begin Label Label5 
  191.       Alignment       =   1  'Right Justify
  192.       Caption         =   "Zip:"
  193.       Height          =   195
  194.       Left            =   3420
  195.       TabIndex        =   13
  196.       Top             =   1740
  197.       Width           =   615
  198.    End
  199.    Begin Label Label4 
  200.       Alignment       =   1  'Right Justify
  201.       Caption         =   "State:"
  202.       Height          =   195
  203.       Left            =   60
  204.       TabIndex        =   12
  205.       Top             =   1740
  206.       Width           =   1215
  207.    End
  208.    Begin Label Label3 
  209.       Alignment       =   1  'Right Justify
  210.       Caption         =   "City:"
  211.       Height          =   195
  212.       Left            =   60
  213.       TabIndex        =   11
  214.       Top             =   1380
  215.       Width           =   1215
  216.    End
  217.    Begin Label Label2 
  218.       Alignment       =   1  'Right Justify
  219.       Caption         =   "Address:"
  220.       Height          =   195
  221.       Left            =   60
  222.       TabIndex        =   10
  223.       Top             =   1020
  224.       Width           =   1215
  225.    End
  226.    Begin Label Label1 
  227.       Alignment       =   1  'Right Justify
  228.       Caption         =   "Name:"
  229.       Height          =   195
  230.       Left            =   60
  231.       TabIndex        =   9
  232.       Top             =   660
  233.       Width           =   1215
  234.    End
  235.    Begin Menu mnuFile 
  236.       Caption         =   "&File"
  237.       Begin Menu mnuExit 
  238.          Caption         =   "E&xit"
  239.       End
  240.    End
  241.    Begin Menu mnuHelp 
  242.       Caption         =   "&Help"
  243.       Begin Menu mnuAbout 
  244.          Caption         =   "&About"
  245.       End
  246.    End
  247. Option Explicit
  248. 'FieldPack Demo Program 2
  249. 'November 1993
  250. 'Software Source
  251. 'Fremont, California
  252. 'tel +1(510)623-7854
  253. 'fax +1(510)651-6039
  254. 'Original programming, including all the
  255. 'really clever report-generation work,
  256. 'by Don Wanless
  257. 'Rewrite and debugging, including the
  258. 'tricky New/Delete/Change stuff, and
  259. 'pedantic commentary and variable
  260. 'renaming, by Sam Cohen
  261. Sub AdjustScrollerRange ()
  262.         Dim i As Integer
  263.         ScrollerChangeEnabled = False
  264.         vscrScroller.Max = NumberOfRecords
  265.         i% = NumberOfRecords / 10
  266.         If i% < 1 Then i% = 1
  267.         vscrScroller.LargeChange = i%
  268.         ScrollerChangeEnabled = True
  269. End Sub
  270. Function BuildRecord () As String
  271.     Dim rec    As String
  272.     Dim wname  As String
  273.     Dim firstn As String
  274.     Dim lastn  As String
  275.     Dim n      As Integer
  276.     wname$ = txtName.Text
  277.     n% = DS_CountDlms(wname$, ",")
  278.     If n% = 0 Then
  279.         ' no comma, so assume firstname [middle] lastname
  280.         wname$ = US_Trim(wname$)
  281.         n% = DS_CountDlms(wname$, " ")
  282.         If n% Then
  283.             lastn$ = DS_GetField(wname$, " ", n% + 1)
  284.             firstn$ = Left$(wname$, DS_FindDlm(wname$, " ", n%) - 1)
  285.             wname$ = lastn$ + ", " + firstn$
  286.         Else
  287.             ' no blanks, use as is
  288.         End If
  289.     ElseIf n% = 1 Then
  290.         ' one comma, so assume lastname, first..., use as is
  291.     Else
  292.         ' more than one comma, ???, use as is
  293.     End If
  294.     rec$ = ""
  295.     rec$ = DS_PutField(rec$, FldDlm$, FIELDNUMBER_NAME, US_Proper(wname$))
  296.     rec$ = DS_PutField(rec$, FldDlm$, FIELDNUMBER_ADDRESS, US_Proper((txtAddress.Text)))
  297.     rec$ = DS_PutField(rec$, FldDlm$, FIELDNUMBER_CITY, US_Proper((txtCity.Text)))
  298.     rec$ = DS_PutField(rec$, FldDlm$, FIELDNUMBER_STATE, UCase((txtState.Text)))
  299.     rec$ = DS_PutField(rec$, FldDlm$, FIELDNUMBER_ZIP, (txtZip.Text))
  300.     rec$ = DS_PutField(rec$, FldDlm$, FIELDNUMBER_AREACODE, (txtAreaCode.Text))
  301.     rec$ = DS_PutField(rec$, FldDlm$, FIELDNUMBER_PHONE, (txtPhone.Text))
  302.     'Rearrange so that the proper sort field is in front:
  303.     rec$ = DS_GetField(rec$, FldDlm$, FirstField) + FldDlm$ + DS_RemoveField(rec$, FldDlm$, FirstField)
  304.     BuildRecord$ = rec$
  305. End Function
  306. Sub cmdDelete_Click ()
  307.     Dim tmp As String
  308.     If FlagNewRecordInProgress Then 'User hit "Delete" to cancel a "New" rec (which isn't really there).
  309.         FlagNewRecordInProgress = False
  310.     Else
  311.         tmp$ = DS_RemoveField(DatabaseMemoryBuffer$, RecDlm$, CurrentRecordNumber)
  312.         DatabaseMemoryBuffer$ = tmp$
  313.         cmdFind.Enabled = False
  314.         lblCurrentSortField.Enabled = False
  315.         FlagFileChanged = True
  316.     End If
  317.     NumberOfRecords = NumberOfRecords - 1
  318.     If CurrentRecordNumber = 1 Then '(code to handle boundary conditions...)
  319.         If NumberOfRecords = 0 Then
  320.             CurrentRecordNumber = 0
  321.         Else
  322.             CurrentRecordNumber = NumberOfRecords   '(Show last rec if we just deleted first rec.)
  323.         End If
  324.     Else
  325.         CurrentRecordNumber = CurrentRecordNumber - 1   '(Normally, show previous record.)
  326.     End If
  327.     AdjustScrollerRange
  328.     DisplayRecord
  329. End Sub
  330. Sub cmdFind_Click ()
  331.     Dim i   As Integer
  332.     Dim FindMe As String
  333.     UpdateIfNecessary
  334.     FindMe$ = txtFindString.Text
  335.     i% = DS_FindField(DatabaseMemoryBuffer$, RecDlm$, 1, FindMe$, 2 + 4) ' case insensitive find "equal to or beginning with"
  336.     If i% < 0 Then
  337.         i% = -i%
  338.     End If
  339.     If i% Then
  340.         CurrentRecordNumber = i%
  341.         DisplayRecord
  342.     End If
  343. End Sub
  344. Sub cmdNew_Click ()
  345.     'Note that this does NOT put a blank record into the database.
  346.     'Instead, it (falsely) increments "NumberOfRecords" and sets
  347.     'CurrentRecordNumber to a fictitious new record at the end
  348.     'of the database.  (This is not good programming technique;
  349.     'it's dangerous to lie to yourself.)
  350.     UpdateIfNecessary
  351.     TextChangeEnabled = False
  352.     txtName.Text = ""
  353.     txtAddress.Text = ""
  354.     txtCity.Text = ""
  355.     txtState.Text = ""
  356.     txtZip.Text = ""
  357.     txtAreaCode.Text = ""
  358.     txtPhone.Text = ""
  359.     NumberOfRecords = NumberOfRecords + 1
  360.     CurrentRecordNumber = NumberOfRecords
  361.     AdjustScrollerRange
  362.     vscrScroller.Value = CurrentRecordNumber
  363.     lblRecordID.Caption = Str$(CurrentRecordNumber) + " of" + Str$(NumberOfRecords)
  364.     FlagNewRecordInProgress = True
  365.     FlagRecordChanged = False
  366.     TextChangeEnabled = True
  367.     txtName.SetFocus
  368. End Sub
  369. Sub cmdReport_Click ()
  370.     UpdateIfNecessary
  371.     ReportFrm.Show 1
  372. End Sub
  373. Sub cmdSort_Click ()
  374.     UpdateIfNecessary
  375.     txtFindString.Text = ""   'Clean up
  376.     ' select sort field
  377.     SortFrm.Show 1
  378.     If SortForm_OK_or_Cancel = 1 Then
  379.         Exit Sub
  380.     End If
  381.     SortRecords
  382.     DisplayRecord
  383. End Sub
  384. Sub DisplayRecord ()
  385.     Dim rec As String
  386.     TextChangeEnabled = False   'Otherwise, setting values into text boxes in
  387.                                 'code would trigger a change event!
  388.     If CurrentRecordNumber > 0 Then
  389.         rec$ = DS_GetField(DatabaseMemoryBuffer$, RecDlm$, CurrentRecordNumber)
  390.         'Rearrange record in "normal" field order for simplicity of field extraction:
  391.         rec$ = DS_InsertField(DS_RemoveField(rec$, FldDlm$, 1), FldDlm$, FirstField, DS_GetField(rec$, FldDlm$, 1))
  392.         txtName.Text = DS_GetField(rec$, FldDlm$, FIELDNUMBER_NAME)
  393.         txtAddress.Text = DS_GetField(rec$, FldDlm$, FIELDNUMBER_ADDRESS)
  394.         txtCity.Text = DS_GetField(rec$, FldDlm$, FIELDNUMBER_CITY)
  395.         txtState.Text = DS_GetField(rec$, FldDlm$, FIELDNUMBER_STATE)
  396.         txtZip.Text = DS_GetField(rec$, FldDlm$, FIELDNUMBER_ZIP)
  397.         txtAreaCode.Text = DS_GetField(rec$, FldDlm$, FIELDNUMBER_AREACODE)
  398.         txtPhone.Text = DS_GetField(rec$, FldDlm$, FIELDNUMBER_PHONE)
  399.     Else
  400.         txtName.Text = ""
  401.         txtAddress.Text = ""
  402.         txtCity.Text = ""
  403.         txtState.Text = ""
  404.         txtZip.Text = ""
  405.         txtAreaCode.Text = ""
  406.         txtPhone.Text = ""
  407.         NumberOfRecords = 1
  408.         CurrentRecordNumber = 1
  409.         FlagNewRecordInProgress = True
  410.     End If
  411.     lblRecordID.Caption = Str$(CurrentRecordNumber) + " of" + Str$(NumberOfRecords)
  412.     vscrScroller.Value = CurrentRecordNumber
  413.     FlagRecordChanged = False   'Initialize trigger.
  414.     TextChangeEnabled = True    'Enable trigger.
  415.     txtName.SetFocus
  416. End Sub
  417. Sub Form_Load ()
  418.     Dim fh    As Integer
  419.     Dim rc    As Integer
  420.     Dim l     As Long
  421.     rc% = FP_Password("Sorry, you'll have to register FIELDPACK to get a password.")
  422.     RecDlm$ = Chr$(13) + Chr$(10)  'CRLF (Carriage-return/line-feed)
  423.     FldDlm$ = ";"
  424.     fh = FreeFile
  425.     DatabaseFileName$ = "c:\fpdemo2.dat"
  426.     Open DatabaseFileName$ For Binary As #fh
  427.     l& = LOF(fh)
  428.     If l& > 65530 Then  '(actually, 65536 -- but I don't trust Microsoft...)
  429.         MsgBox "File too big (over 64KB)!", 48, "FieldPack Demo Program 2"
  430.         End
  431.     End If
  432.     DatabaseMemoryBuffer$ = String$(l&, " ")  'See the next line of code...
  433.     Get #fh, , DatabaseMemoryBuffer$    'Read entire file contents into memory (max 64 KB!!).
  434.     Close #fh
  435.     'Normally (see SaveIntoFile procedure), there's a final CRLF, after the last piece of data;
  436.     'we'll remove it, if it's there.
  437.     NumberOfRecords = DS_CountDlms(DatabaseMemoryBuffer$, RecDlm$)
  438.     DatabaseMemoryBuffer$ = DS_RemoveField(DatabaseMemoryBuffer$, RecDlm$, NumberOfRecords + 1)
  439.     If DatabaseMemoryBuffer = "" Then NumberOfRecords = 0
  440.     AdjustScrollerRange
  441.     FirstField = 1
  442.     SortField = 1
  443.     lblCurrentSortField.Enabled = True
  444.     lblCurrentSortField.Caption = "Name"
  445.     If NumberOfRecords = 0 Then
  446.         CurrentRecordNumber = 0
  447.     Else
  448.         SortRecords 'This is redundant (see SaveIntoFile procedure), but whatthehell...
  449.         CurrentRecordNumber = 1
  450.     End If
  451.     FlagFileChanged = False
  452.     FlagRecordChanged = False
  453.     FlagNewRecordInProgress = False
  454.     EditFrm.Show    'Necessary because of the SetFocus
  455.                     'call in the DisplayRecord procedure.
  456.     DisplayRecord
  457. End Sub
  458. Sub mnuAbout_Click ()
  459.     AboutFrm.Show 1
  460. End Sub
  461. Sub mnuExit_Click ()
  462.     UpdateIfNecessary
  463.     If FlagFileChanged Then
  464.         SortField = 1  'We chose to always save the file sorted by "Name."
  465.         SortRecords
  466.         SaveIntoFile
  467.     End If
  468.     Unload EditFrm  'Bye...
  469. End Sub
  470. Sub SaveIntoFile ()
  471.     Dim fh   As Integer
  472.     Dim crlf As String
  473.     crlf$ = Chr$(13) + Chr$(10)
  474.     fh = FreeFile
  475.     Kill DatabaseFileName$  'If we didn't do this, we couldn't shorten the file contents.
  476.     Open DatabaseFileName$ For Binary As #fh
  477.     Put #fh, , DatabaseMemoryBuffer$
  478.     Put #fh, , crlf$    'We add a final CRLF so that text editors can read the file; each
  479.                         'record appears as a line of text.  See Form_Load.
  480.     Close #fh
  481.     FlagFileChanged = False 'We put this here in case you want to expand this example
  482.                             'into a more sophisticated program, with a "Save" menu item
  483.                             '(and maybe also "Open," "Save As," etc.)
  484. End Sub
  485. Sub SortRecords ()
  486.     Dim i   As Integer
  487.     Dim rec As String
  488.     Dim sf  As String
  489.     ' sort the items using a sorted list box
  490.     ' clear the list box
  491.     lstSortingListBox.Clear
  492.     ' load items into list box from our buffer...
  493.     For i% = 1 To NumberOfRecords
  494.         rec$ = DS_GetField(DatabaseMemoryBuffer$, RecDlm$, i%)
  495.         'First, rearrange record in "normal" field order for simplicity of field extraction:
  496.         rec$ = DS_InsertField(DS_RemoveField(rec$, FldDlm$, 1), FldDlm$, FirstField, DS_GetField(rec$, FldDlm$, 1))
  497.         'Now, rearrange so that the newly-chosen sort field is in front:
  498.         rec$ = DS_InsertField(DS_RemoveField(rec$, FldDlm$, SortField), FldDlm$, 1, DS_GetField(rec$, FldDlm$, SortField))
  499.         lstSortingListBox.AddItem rec$
  500.     Next i%
  501.     ' clear our buffer
  502.     DatabaseMemoryBuffer$ = ""
  503.     ' Take records from list box (now in sort sequence) and put them back into our buffer.
  504.     For i% = 1 To NumberOfRecords
  505.         DatabaseMemoryBuffer$ = DS_PutField(DatabaseMemoryBuffer$, RecDlm$, i%, (lstSortingListBox.List(i% - 1)))
  506.     Next i%
  507.     FlagFileChanged = 1
  508.     ' clear list box to give memory back
  509.     lstSortingListBox.Clear
  510.     ' Record the new database field arrangement:
  511.     FirstField = SortField
  512.     ' show the first record (whoever called us will then call DisplayRecord)
  513.     CurrentRecordNumber = 1
  514.     cmdFind.Enabled = True
  515.     lblCurrentSortField.Enabled = True
  516. End Sub
  517. Sub txtAddress_Change ()
  518.     If TextChangeEnabled Then FlagRecordChanged = True
  519. End Sub
  520. Sub txtAreaCode_Change ()
  521.     If TextChangeEnabled Then FlagRecordChanged = True
  522. End Sub
  523. Sub txtCity_Change ()
  524.     If TextChangeEnabled Then FlagRecordChanged = True
  525. End Sub
  526. Sub txtName_Change ()
  527.     If TextChangeEnabled Then FlagRecordChanged = True
  528. End Sub
  529. Sub txtPhone_Change ()
  530.     If TextChangeEnabled Then FlagRecordChanged = True
  531. End Sub
  532. Sub txtState_Change ()
  533.     If TextChangeEnabled Then FlagRecordChanged = True
  534. End Sub
  535. Sub txtZip_Change ()
  536.     If TextChangeEnabled Then FlagRecordChanged = True
  537. End Sub
  538. Sub UpdateIfNecessary ()
  539.     'This routine should be called everywhere there's an indication that the user
  540.     'may be finished looking at a displayed record.
  541.     Dim rec As String
  542.     If FlagRecordChanged Then   '(Whether old record or new record...)
  543.         rec$ = BuildRecord()
  544.         If (Len(rec$) < (65530 - Len(DatabaseMemoryBuffer$))) Then
  545.             DatabaseMemoryBuffer$ = DS_PutField(DatabaseMemoryBuffer$, RecDlm$, CurrentRecordNumber, rec$)
  546.             FlagFileChanged = True
  547.             cmdFind.Enabled = False
  548.             lblCurrentSortField.Enabled = False
  549.             FlagNewRecordInProgress = False
  550.         Else
  551.             MsgBox "Changes not saved -- database too large (64KB limit).", 48, "FieldPack Demo Program 2"
  552.         End If
  553.         FlagRecordChanged = False
  554.     ElseIf FlagNewRecordInProgress Then '(User had a "New" record up, but didn't enter anything.)
  555.         NumberOfRecords = NumberOfRecords - 1
  556.         CurrentRecordNumber = CurrentRecordNumber - 1
  557.         AdjustScrollerRange
  558.         FlagNewRecordInProgress = False
  559.         DisplayRecord   'Display the last record in the buffer.  (If none, will put up "New" rec.)
  560.     End If
  561. End Sub
  562. Sub vscrScroller_Change ()
  563.     If ScrollerChangeEnabled Then UpdateIfNecessary
  564.     If vscrScroller.Value = 0 Then
  565.         CurrentRecordNumber = 1
  566.     Else
  567.         CurrentRecordNumber = vscrScroller.Value
  568.     End If
  569.     DisplayRecord
  570. End Sub
  571. Sub vscrScroller_Scroll ()
  572.     UpdateIfNecessary
  573.     If vscrScroller.Value = 0 Then
  574.         CurrentRecordNumber = 1
  575.     Else
  576.         CurrentRecordNumber = vscrScroller.Value
  577.     End If
  578.     DisplayRecord
  579. End Sub
  580.